<template>
  <div class="instance-attr-form">
    <el-form ref="myform" v-loading="requestLoading" :model="instance" label-width="180px" size="mini">
      <el-row :gutter="20">
        <el-col :span="12">
          <el-form-item label="ID：">
            {{ instance._id }}
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="唯一标识：">
            {{ instance.code }}
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="名称：" prop="name">
            {{ instance.name }}
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="所属模型：">
            <router-link :to="'/cmdb/schemas/' + instance.schemadef._id" class="el-button el-button--text el-button" style="padding-top: 0;">{{ instance.schemadef.name }}</router-link>
          </el-form-item>
        </el-col>
        <el-col v-for="(vulue, key) in instance.attrs" :key="key" :span="12">
          <el-form-item class="attr-item" :label="getAttrName(key) + '：'">
            <span>
              <span v-if="key !== editKey && getAttrDType(key) !== 'foreign'">{{ getAttrValue(key, vulue) }}</span>
              <router-link v-if="key !== editKey && getAttrDType(key) === 'foreign'" :to="'/cmdb/instances/' + instance.attrs[key]" class="el-button el-button--text el-button" style="padding-top: 0;">
                <foreign-select v-model="instance.attrs[key]" :disabled="true" :schema="getForeignKey(key)" :width="150" />
              </router-link>
              <string-input v-if="key === editKey && getAttrDType(key) === 'string'" v-model="instance.attrs[key]" style="display: inline-block;" />
              <bool-checkbox v-if="key === editKey && getAttrDType(key) === 'bool'" v-model="instance.attrs[key]" style="display: inline-block;" />
              <number-input v-if="key === editKey && getAttrDType(key) === 'number'" v-model="instance.attrs[key]" style="display: inline-block; max-width: 200px;" />
              <enum-select v-if="key === editKey && getAttrDType(key) === 'enum'" v-model="instance.attrs[key]" :options="getEnmuOptions(key)" style="display: inline-block;" />
              <foreign-select
                v-if="key === editKey && getAttrDType(key) === 'foreign'"
                v-model="instance.attrs[key]"
                :schema="getForeignKey(key)"
                :width="200"
                style="display: inline-block;"
              />
              <datasource-select
                v-if="key === editKey && getAttrDType(key) === 'datasource'"
                v-model="instance.attrs[key]"
                :options="getEnmuOptions(key)"
                :url="getDatasource(key).url"
                :value-key="getDatasource(key).valueKey"
                :label-key="getDatasource(key).labelKey"
                :response-key="getDatasource(key).responseKey"
                :width="200"
                style="display: inline-block;"
              />
              <el-button title="编辑" type="text" size="mini" icon="el-icon-edit" style="margin-left: 10px;" @click="onEditAttr(key)" />
              <el-button v-show="key === editKey" title="取消" type="text" size="mini" icon="el-icon-switch-button" @click="onCancelEditAttr(key)" />
              <el-button v-show="instance.attrs[key] !== getOriginalAttrVal(key)" title="保存" type="text" size="mini" icon="el-icon-check" @click="onSaveAttr(key)" />
            </span>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
  </div>
</template>

<script>
import { detail as instanceDetail, updateAttr } from '@neu/cmdb-ui/api/instance'
import { detail as schemaDetail } from '@neu/cmdb-ui/api/schema'
import { deepClone, parseTime } from '@neu/biz-core/utils'

export default {
  name: 'CmdbInstanceAttrForm',
  props: {
    instanceId: {
      required: true,
      type: String
    }
  },
  data() {
    return {
      requestLoading: false,
      instance: {
        name: '',
        schemadef: {
          _id: '',
          name: ''
        },
        attrs: {}
      },
      editKey: '',
      cloneAttrs: {},
      schemaAttrs: []
    }
  },
  created() {
    this.fetch()
  },
  methods: {
    // 获取实例详细信息
    fetch: function() {
      this.requestLoading = true
      instanceDetail(this.instanceId).then(response => {
        const _attrs = response.data.attrs
        const attrs = _attrs.reduce((o, item) => { o[item.key] = item.value; return o }, {})
        this.cloneAttrs = deepClone(attrs)

        schemaDetail(response.data.schemadef._id).then(response2 => {
          const instance = { ...response.data, attrs, schemadef: response2.data }
          this.instance = instance

          let schemaAttrs = response2.data.attrs
          const categoryAttrs = response2.data.category.attrs || []
          schemaAttrs = [...schemaAttrs, ...categoryAttrs]

          this.schemaAttrs = Object.freeze(schemaAttrs)
          this.requestLoading = false
        })
      })
    },

    // 从模型定义中获取属性名称
    getAttrName(k) {
      const attr = this.schemaAttrs.find(it => it.field === k)
      return attr ? attr.name : k
    },

    // 获取格式化属性值
    getAttrValue(k, v) {
      const attr = this.schemaAttrs.find(it => it.field === k)
      if (attr.dtype === 'date') {
        return parseTime(v)
      } else if (attr.dtype === 'enum') {
        const enumItem = attr.enums.find(e => e.value === v)
        return enumItem ? enumItem.label : ''
      } else if (attr.dtype === 'bool') {
        return v ? '是' : '否'
      }
      return v !== null ? v : '未设置'
    },

    // 获取属性原始值，判断属性值是否改变
    getOriginalAttrVal(k) {
      return this.cloneAttrs[k]
    },

    // 设置属性为编辑状态
    onEditAttr(k) {
      this.editKey = k
    },

    // 取消属性的编辑状态
    onCancelEditAttr(k) {
      this.editKey = ''
      this.instance.attrs[k] = this.getOriginalAttrVal(k)
    },

    // 提交单个属性值的改变
    onSaveAttr(k) {
      updateAttr(this.instanceId, k, this.instance.attrs[k]).then(response => {
        this.cloneAttrs[k] = this.instance.attrs[k]
        this.editKey = ''
      })
    },

    // 获取属性的数据类型定义
    getAttrDType(k) {
      const schemaAttr = this.schemaAttrs.find(it => it.field === k)
      return schemaAttr ? schemaAttr.dtype : 'string'
    },

    // 获取枚举属性的枚举项定义
    getEnmuOptions(k) {
      const schemaAttr = this.schemaAttrs.find(it => it.field === k)
      return schemaAttr ? schemaAttr.enums : []
    },

    // 获取数据源属性的数据源定义
    getDatasource(k) {
      const schemaAttr = this.schemaAttrs.find(it => it.field === k)
      return schemaAttr ? schemaAttr.datasource : {}
    },

    // 获取外键属性的定义
    getForeignKey(k) {
      const schemaAttr = this.schemaAttrs.find(it => it.field === k)
      return schemaAttr ? schemaAttr.dvalue : ''
    }
  }
}
</script>

<style lang="scss">
  .instance-attr-form {
    min-height: calc(100vh - 200px);
    .attr-item {
      button {
        display: none;
      }
      &:hover  {
        button {
          display: inline-block;
        }
      }
    }
  }
</style>
